﻿using System;
using System.Diagnostics;
using System.Windows.Controls;
using Alimentador.CustomControls;
using Alimentador.Foods;
using PdfSharp.Drawing;
using PdfSharp.Drawing.Layout;
using PdfSharp.Pdf;

namespace Alimentador.PDFHelper
{
    public class PDFHelper
    {
        private static int m_YPositionToStart;

        private static PdfDocument document;
        private static XGraphics gfx;
        private static XTextFormatter tf;

        private static PdfPage CurrentPage;
        private static int m_pageNumber;

        private static XFont NormalFont;
        private static XFont NormalFontBold;

        private static string m_jpegLogoPath = "Images/IPS_logo.png";

        public static string JpegLogoPath
        {
            set
            {
                m_jpegLogoPath = value;
            }
            get
            {
                return m_jpegLogoPath;
            }
        }

        public static void SavePlan(PersonPatient currentPatient, Week wk)
        {
            initFile(currentPatient, wk.DayList.Count);
            
            foreach (Day wd in wk.DayList)
            {
                XRect RectangleForWeekDay = new XRect(270, m_YPositionToStart, 200, 60);
                tf.DrawString(wd.DayName.ToString(), NormalFontBold, XBrushes.SteelBlue, RectangleForWeekDay, XStringFormats.TopLeft);

                foreach (Meal mealList in wd.MealList)
                {
                    AddMealLine();
                    XRect RectangleForMealDescription = new XRect(20, m_YPositionToStart, 200, 60);
                    tf.DrawString(mealList.MealDescription, NormalFont, XBrushes.Black, RectangleForMealDescription, XStringFormats.TopLeft);

                    foreach (FoodEssencial fb in mealList.FoodList)
                    {
                        XBrush brush = new XSolidBrush(XColor.FromArgb(255, 39, 130, 175));

                        AddFoodLine();
                        XRect RectangleForFood = new XRect(30, m_YPositionToStart, 500, 60);
                        tf.DrawString(fb.Name, NormalFont, brush, RectangleForFood, XStringFormats.TopLeft);

                        if (fb is FoodEssencial)
                        {
                            FoodEssencial theFood = (FoodEssencial)fb;
                            XRect RectangleForQuantity = new XRect(540, m_YPositionToStart, 100, 60);
                            tf.DrawString(theFood.Quantity + theFood.Unit, NormalFont, brush, RectangleForQuantity, XStringFormats.TopLeft);
                        }
                    }
                }

                AddWeekDayLine();
            }

            SaveFile(currentPatient.PatName);
        }

        private static void initFile(PersonPatient currentPatient, int WeekDayCount)
        {
            m_pageNumber = 0;
            document = new PdfDocument();

            document.Info.Title = "Created by Plano Alimentar";
            document.Info.Author = "Alimentador";
            document.Info.Subject = "Alimentador";
            document.Info.Keywords = "Alimentador";

            CreateNewPage(false);

            string jpegLogoPath = m_jpegLogoPath;
            XImage xi = XImage.FromFile(jpegLogoPath);
            gfx.DrawImage(xi, 20, 15);

            NormalFont = new XFont("Verdana", 12, XFontStyle.Regular);
            NormalFontBold = new XFont("Verdana", 13, XFontStyle.Bold);

            string TodayDate_str = DateTime.Now.ToString("dd-MM-yyyy");
            XRect RectangleForTodayDate = new XRect(20, 65, 450, 15);
            tf.DrawString("Estudo dietético realizado a " + TodayDate_str  + " por: Plano Alimentar- IPS", NormalFont, XBrushes.Black, RectangleForTodayDate, XStringFormats.TopLeft);

            XRect RectangeForPatName = new XRect(20, 80, 450, 60);
            tf.DrawString("Nome: " + currentPatient.PatName, NormalFont, XBrushes.Black, RectangeForPatName, XStringFormats.TopLeft);

            XRect RectangeForPatWeight = new XRect(20, 95, 450, 60);
            tf.DrawString("Peso (Kg): " + currentPatient.PatWeight, NormalFont, XBrushes.Black, RectangeForPatWeight, XStringFormats.TopLeft);

            XRect RectangeForPatHeight = new XRect(160, 95, 450, 60);
            tf.DrawString("Altura (Cm): " + currentPatient.PatHeight, NormalFont, XBrushes.Black, RectangeForPatHeight, XStringFormats.TopLeft);

            XRect RectangeForPatWaist = new XRect(320, 95, 450, 60);
            tf.DrawString("Cintura (Cm): " + currentPatient.PatWaist, NormalFont, XBrushes.Black, RectangeForPatWaist, XStringFormats.TopLeft);

            XRect RectangeForPatIMC = new XRect(470, 95, 450, 60);
            tf.DrawString("IMC: " + string.Format("{0:N2}", currentPatient.PatIMC), NormalFont, XBrushes.Black, RectangeForPatIMC, XStringFormats.TopLeft);

            XRect RectangeForPatPC = new XRect(20, 110, 450, 60);
            tf.DrawString("P.C.: " + MainHelper.GetEnumDescription(currentPatient.PatPC), NormalFont, XBrushes.Black, RectangeForPatPC, XStringFormats.TopLeft);

            XRect RectangeForPlanRecTitle = new XRect(20, 135, 450, 60);
            tf.DrawString("Plano Alimentar - IPS recomenda:", NormalFontBold, XBrushes.Black, RectangeForPlanRecTitle, XStringFormats.TopLeft);

            XRect RectangeForEnergValueTitle = new XRect(20, 150, 450, 60);
            tf.DrawString("Valor energético: " + string.Format("{0:N2}", FoodFormulas.RecommendedEnergy(WeekDayCount, currentPatient)) + " Kcal. distribuido por:" , NormalFont, XBrushes.Black, RectangeForEnergValueTitle, XStringFormats.TopLeft);

            XRect RectangeForEnergOriginTitle = new XRect(30, 165, 450, 60);
            tf.DrawString("Origem da energia distribuida por:", NormalFont, XBrushes.Black, RectangeForEnergOriginTitle, XStringFormats.TopLeft);

            XRect RectangeForCarbon = new XRect(40, 180, 450, 60);
            tf.DrawString("Hidratos de carbono(g): " + string.Format("{0:N2}", FoodFormulas.RecommendedCarbonHidrats(WeekDayCount, currentPatient)), NormalFont, XBrushes.Black, RectangeForCarbon, XStringFormats.TopLeft);
            XRect RectangeForProtein = new XRect(40, 195, 450, 60);
            tf.DrawString("Proteínas(g): " + string.Format("{0:N2}", FoodFormulas.RecommendedProtein(WeekDayCount, currentPatient)), NormalFont, XBrushes.Black, RectangeForProtein, XStringFormats.TopLeft);
            XRect RectangeForLipids = new XRect(40, 210, 450, 60);
            tf.DrawString("Lípidos(g): " + string.Format("{0:N2}", FoodFormulas.RecommendedLipids(WeekDayCount, currentPatient)), NormalFont, XBrushes.Black, RectangeForLipids, XStringFormats.TopLeft);

            XRect RectangeForColestTitle = new XRect(400, 165, 450, 60);
            tf.DrawString("Colesterol", NormalFont, XBrushes.Black, RectangeForColestTitle, XStringFormats.TopLeft);
            XRect RectangeForColest = new XRect(410, 180, 450, 60);
            tf.DrawString("Colesterol(mg): " + string.Format("{0:N2}", FoodFormulas.RecommendedColesterol(WeekDayCount)), NormalFont, XBrushes.Black, RectangeForColest, XStringFormats.TopLeft);

            XRect RectangeForColestMacroTitle = new XRect(400, 195, 450, 60);
            tf.DrawString("Macronutrientes", NormalFont, XBrushes.Black, RectangeForColestMacroTitle, XStringFormats.TopLeft);
            XRect RectangeForMacro = new XRect(410, 210, 450, 60);
            tf.DrawString("Fibra(g): " + string.Format("{0:N2}", FoodFormulas.RecommendedFiber(WeekDayCount)), NormalFont, XBrushes.Black, RectangeForMacro, XStringFormats.TopLeft);

            m_YPositionToStart = 250;
        }

        public static void SavePlan(PersonPatient CurrentPatient, ItemCollection WeekDayList)
        {
            initFile(CurrentPatient, WeekDayList.Count);

            foreach (WeekDay wd in WeekDayList)
            {
                XRect RectangleForWeekDay = new XRect(270, m_YPositionToStart, 200, 60);
                tf.DrawString(wd.Header.ToString(), NormalFontBold, XBrushes.SteelBlue, RectangleForWeekDay, XStringFormats.TopLeft);

                foreach (MealCtrl mealList in wd.GetMealList)
                {
                    AddMealLine();
                    XRect RectangleForMealDescription = new XRect(20, m_YPositionToStart, 200, 60);
                    tf.DrawString(mealList.MealDescription, NormalFont, XBrushes.Black, RectangleForMealDescription, XStringFormats.TopLeft);

                    foreach (FoodBase fb in mealList.GetFoodList)
                    {
                        XBrush brush = new XSolidBrush(XColor.FromArgb(255, 39, 130, 175));

                        AddFoodLine();
                        XRect RectangleForFood = new XRect(30, m_YPositionToStart, 500, 60);
                        tf.DrawString(fb.GetName, NormalFont, brush, RectangleForFood, XStringFormats.TopLeft);

                        if (fb is Food)
                        {
                            Food theFood = (Food)fb;
                            XRect RectangleForQuantity = new XRect(540, m_YPositionToStart, 100, 60);
                            tf.DrawString(theFood.GetQuantity + theFood.GetUnit, NormalFont, brush, RectangleForQuantity, XStringFormats.TopLeft);
                        }
                    }
                }

                AddWeekDayLine();
            }

            SaveFile(CurrentPatient.PatName);
        }

        private static void SaveFile(string CurrentPatient)
        {
            AddPageNumber();
            if (m_jpegLogoPath == "Images/IPS_logo.png")
            {
                AddDefaultWaterMark();
            }
            // Save the document...
            string filename = CurrentPatient + "_PlanoAlimentar.pdf";
            document.Save(filename);

            // ...and start a viewer.
            Process.Start(filename);
        }

        private static void AddWeekDayLine()
        {
            m_YPositionToStart += 40;
            EndPageValidation();
        }

        private static void EndPageValidation()
        {
            if (m_YPositionToStart > 780)
            {
                CreateNewPage();
            }
        }

        private static void CreateNewPage(bool waterMark_bool = true)
        {
            if (waterMark_bool)
            {
                AddPageNumber();
                AddDefaultWaterMark();
            }

            // Create an empty page
            CurrentPage = document.AddPage();

            // Get an XGraphics object for drawing
            gfx = XGraphics.FromPdfPage(CurrentPage);
            tf = new XTextFormatter(gfx);

            XFont TitleFont = new XFont("Verdana", 20, XFontStyle.Bold);
            gfx.DrawString("Plano Alimentar", TitleFont, XBrushes.Black, new XRect(0, 20, CurrentPage.Width, CurrentPage.Height), XStringFormats.TopCenter);

            m_YPositionToStart = 80;
            m_pageNumber++;
        }

        private static void AddDefaultWaterMark()
        {
            Draw_WaterMark("IPS", gfx, CurrentPage.Width, CurrentPage.Height);
        }

        private static void AddMealLine()
        {
            m_YPositionToStart += 30;
            EndPageValidation();
        }

        private static void AddFoodLine()
        {
            m_YPositionToStart += 15;
            EndPageValidation();
        }

        private static void AddPageNumber()
        {
            XFont PageNumberFont = new XFont("Verdana", 8, XFontStyle.Regular);

            XRect RectangleForFood = new XRect(560, 800, 50, 50);
            tf.DrawString(m_pageNumber.ToString(), PageNumberFont, XBrushes.LightBlue, RectangleForFood, XStringFormats.TopLeft);
        }

        private static void Draw_WaterMark(string text, XGraphics gfx, double pageWidth, double pageHeight)
        {
            int fontSize = 400;
            XSize size = gfx.MeasureString(text, new XFont("Verdana", fontSize, XFontStyle.BoldItalic));

            gfx.TranslateTransform(pageWidth / 2, pageHeight / 2);
            gfx.RotateTransform(-Math.Atan(pageHeight / pageWidth) * 180 / Math.PI);
            gfx.TranslateTransform(-pageWidth / 2, -pageHeight / 2);

            XStringFormat format = new XStringFormat();
            format.Alignment = XStringAlignment.Near;
            format.LineAlignment = XLineAlignment.Near;

            XBrush brush = new XSolidBrush(XColor.FromArgb(20, 200, 200, 200));

            gfx.DrawString(text, new XFont("Verdana", fontSize, XFontStyle.Bold), brush, new XPoint((pageWidth - size.Width) / 2, (pageHeight - size.Height) / 2), format);
        }
    }
}